﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using Fuse8.DomainFramework.Common.Locator;
using Fuse8.DomainFramework.Practices.DataAccess.Commands;
using Fuse8.DomainFramework.Practices.Domain.Interfaces;

namespace Fuse8.DomainFramework.Practices.SystemFacade
{
	public static class CommandNameFacade
	{
		public static string GetCommandName<TDomain, TParameter>()
		{
			var domainType = typeof(TDomain);
			if (domainType.IsGenericType && domainType.GetGenericTypeDefinition().Equals(typeof(GenericList<,>)))
			{
				domainType = domainType.GetGenericArguments()[0];
				return (string)GenericGetCommandName.MakeGenericMethod(domainType, typeof (TParameter)).Invoke(Current, new object[0]);
			}
			return Current.GetCommandName<TDomain, TParameter>();
		}

		public static void SetCurrent(ICommandNameFactory value)
		{
			_commandNameFactory = value;
		}

		private static readonly MethodInfo GenericGetCommandName =
			((MethodCallExpression) ((Expression<Action>) (() => Current.GetCommandName<int, int>())).Body).Method.
				GetGenericMethodDefinition();

		private static ICommandNameFactory _commandNameFactory;
		private static ICommandNameFactory Current
		{
			get
			{
				return _commandNameFactory ??
						(_commandNameFactory = new BaseCommandNameFactory());
			}
		}
	}
}